package com.sa.iam.service.impl;

import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sa.iam.dto.LoginDTO;
import com.sa.iam.service.AuthService;
import com.sa.user.api.dto.RoleDTO;
import com.sa.user.api.dto.UserDTO;
import com.sa.user.api.feignapi.RoleApi;
import com.sa.user.api.feignapi.UserApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author Architecture Station
 * @version 1.0
 * @website 
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AuthServiceImpl implements AuthService {

    private final UserApi userApi;
    private final RoleApi roleApi;
    private final RedisTemplate redisTemplate;

    @Override
    public SaResult login(LoginDTO loginDTO) {
        UserDTO userDTO = parseToUserDTO(loginDTO);
        try {
            SaResult response = userApi.login(userDTO);

            if (response.getCode() == SaResult.CODE_SUCCESS) {
                // 用户验证成功
                UserDTO user = new ObjectMapper().convertValue(response.getData(), UserDTO.class);

                // 使用 Sa-Token 进行登录
                StpUtil.login(user.getId(), SaLoginConfig
                        .setExtra("fullName", user.getFullName()));

                // 用户登录成功之后，缓存维护用户-角色数据
                List<RoleDTO> roleDTOList = roleApi.loadRoles(user.getId());
                List<String> roleNames = roleDTOList.stream()
                        .map(RoleDTO::getName)
                        .collect(Collectors.toList());
                // 将角色名称信息存入 Redis    user-roles-1  ,  [管理员,财务,...]
                redisTemplate.opsForValue().set("user-roles-" + user.getId(), roleNames, 60 * 60 * 24, TimeUnit.SECONDS);
                return SaResult.ok("登录成功");
            } else {
                return SaResult.error(response.getMsg());
            }
        } catch (Exception e) {
            log.error("Error during login request", e);
            return SaResult.error("Server error: " + e.getMessage());
        }
    }

    @Override
    public SaResult sortToken() {
        SaResult response = userApi.test();
        return SaResult.ok(response.getMsg());
    }

    private UserDTO parseToUserDTO(LoginDTO loginDTO) {
        UserDTO userDTO = new UserDTO();
        userDTO.setUsername(loginDTO.getUsername());
        userDTO.setPassword(loginDTO.getPassword());
        return userDTO;
    }


}
